package model.beans;

import core.Database;
import java.io.Serializable;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;

/**
 *
 * @author Danon
 */
public class DirectedGraphBean implements Serializable {
//    public final long serialVersionID = 1L;
//
//    public DirectedGraphBean() {
//    }
    
//    public static void main(String[] args) {
//        //File f = new File("E:\\");
//        //add(f);
//        Random r = new Random(System.nanoTime());
//        for(int i=0;i<10_000_000;i++) {
//            addlink("link "+i, r.nextFloat()*1024*1024*10+1024, r.nextInt(200000), r.nextInt(200000));
//        }
//    }
    
    public static synchronized void addVertex(RouterBean r) {
        PreparedStatement ps = null;
        try {
            Connection c = Database.getInstance().getConnection();
            ps = c.prepareStatement("insert into routers (router_id, title) "
                    + "values (gen_router_id.nextval, ?)");
            ps.setString(1, r.getName());
            ps.executeUpdate();
            c.commit();
        } catch (Exception ex) {
            logger.debug("Failed to add router: "+ex.getMessage());
        } finally {
            try {
                ps.close();
            } catch (SQLException ex) {}
        }
    }
    
    public static synchronized List<RouterBean> getVertices(int limit) {
        List<RouterBean> routers = new ArrayList<>();
        try {
            Connection c = Database.getInstance().getConnection();
            try (PreparedStatement ps = c.prepareStatement("select router_id, title from routers where rownum<=? order by title")) {
                ps.setInt(1, limit);
                ResultSet rs = ps.executeQuery();
                // if-while
                while(rs.next()) {
                    RouterBean r = new RouterBean(rs.getInt("router_id"), rs.getString("title"));
                    routers.add(r);
                }
                rs.close();
            }
        } catch (Exception ex) {
            logger.debug("Failed to obtain the list of routers: "+ex.getMessage());
        }
        return routers;
    }
    
    public static synchronized List<LinkBean> getIncidentVertices(RouterBean r, float minBandwidth) {
        List<LinkBean> lst = new ArrayList<>();
        try {
            Connection c = Database.getInstance().getConnection();
            try(PreparedStatement ps = c.prepareStatement("select link_id, title, src_router, dst_router, bandwidth "
                    + "from links where (src_router = ? or dst_router = ?) and bandwidth >= ?")) {
                ps.setInt(1, r.getId());
                ps.setInt(2, r.getId());
                ps.setFloat(3, minBandwidth);
                ResultSet rs = ps.executeQuery();
                while(rs.next()) {
                    LinkBean l = new LinkBean(rs.getInt("link_id"), rs.getString("title"), rs.getFloat("bandwidth"));
                    l.setRouter1(RouterBean.loadById(rs.getInt("src_router")));
                    l.setRouter2(RouterBean.loadById(rs.getInt("dst_router")));
                    lst.add(l);
                }
                rs.close();
            }
        } catch (Exception ex) {
            logger.debug("Failed to get neighbour routers for "+r+": "+ex.getMessage());
        }
        return lst;
    }
    

    private static void addlink(String title, float bandwidth, int r1, int r2) {
        PreparedStatement ps = null;
        if(r1==r2) return;
        try {
            Connection c = Database.getInstance().getConnection();
            ps = c.prepareStatement("insert into links (link_id, title, bandwidth, src_router, dst_router) "
                    + "values (gen_link_id.nextval, ?, ?,?,?)");
            ps.setString(1, title);
            ps.setFloat(2, bandwidth);
            ps.setInt(3, r1);
            ps.setInt(4, r2);
            ps.executeUpdate();
            c.commit();
        } catch (Exception ex) {
            logger.debug("Failed to add link: "+ex);
        } finally {
            try {
                ps.close();
            } catch (SQLException ex) {}
        }
    }

    public static int size() {
        int result = 0;
        try {
            Connection c = Database.getInstance().getConnection();
            try (PreparedStatement ps = c.prepareStatement("select count(*) cnt from routers")) {
                ResultSet rs = ps.executeQuery();
                if(rs.next()) {
                   result = rs.getInt("cnt");
                }
                rs.close();
            }
        } catch (Exception ex) {
            logger.debug("Failed to identify number of routers: "+ex.getMessage());
        }
        return result;
    }
    
    private static final Logger logger = Logger.getLogger(DirectedGraphBean.class);
    
}

